home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / javax / swing / JOptionPane.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  79.1 KB  |  1,944 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)JOptionPane.java    1.44 98/08/28
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package javax.swing;
  16.  
  17. import java.awt.BorderLayout;
  18. import java.awt.Component;
  19. import java.awt.Container;
  20. import java.awt.Dialog;
  21. import java.awt.Dimension;
  22. import java.awt.Frame;
  23. import java.awt.Toolkit;
  24. import java.beans.PropertyChangeEvent;
  25. import java.beans.PropertyChangeListener;
  26. import java.awt.event.WindowAdapter;
  27. import java.awt.event.WindowEvent;
  28. import java.io.IOException;
  29. import java.io.ObjectInputStream;
  30. import java.io.ObjectOutputStream;
  31. import java.io.Serializable;
  32. import java.util.Vector;
  33. import javax.swing.plaf.OptionPaneUI;
  34. import javax.accessibility.*;
  35.  
  36. /**
  37.  * JOptionPane makes it easy to pop up a standard dialog box that
  38.  * prompts users for a value or informs them of something. While the 
  39.  * class may appear complex because of the large number of methods, almost
  40.  * all uses of this class are one-line calls to one of the static 
  41.  * <code>showXxxDialog</code> methods shown below:
  42.  * <blockquote>
  43.  * <table>
  44.  * <tr align=top><td>showConfirmDialog<td>Asks a confirming question, 
  45.  *                   like yes/no/cancel.
  46.  * <tr align=top><td>showInputDialog<td>Prompt for some input.
  47.  * <tr align=top><td>showMessageDialog<td>Tell the user about something 
  48.  *                                        that has happened.
  49.  * <tr align=top><td>showOptionDialog<td>The Grand Unification of the above three.
  50.  * </table>
  51.  * </blockquote>
  52.  * Each of these methods also comes in a <code>showInternalXXX</code>
  53.  * flavor, which uses an internal frame to hold the dialog box (see
  54.  * {@link JInternalFrame}).
  55.  * Multiple convenience methods have also been defined -- overloaded 
  56.  * versions of the basic methods that use different parameter lists.
  57.  * <p>
  58.  * All dialogs are modal. Each <code>showXxxDialog</code> method blocks 
  59.  * the current thread until the user's interaction is complete.
  60.  * <p>
  61.  * <table cellspacing=6 cellpadding=4 border=0 align=right>
  62.  * <tr>
  63.  * <td bgcolor=#FFe0d0 rowspan=2>
  64.  * icon
  65.  * <td bgcolor=#FFe0d0>
  66.  * message
  67.  * <tr>
  68.  * <td bgcolor=#FFe0d0>
  69.  * input value
  70.  * <tr>
  71.  * <td bgcolor=#FFe0d0 colspan=2>
  72.  * option buttons
  73.  * </table>
  74.  * The basic appearance of one of these dialog boxes is generally
  75.  * similar to the picture at the right, although the various look-and-feels are
  76.  * ultimatly responsible for the final result.
  77.  * <br clear=all>
  78.  * <p>
  79.  * <b>Parameters:</b><br>
  80.  * The parameters to these methods follow consistent patterns:
  81.  * <blockquote>
  82.  * <dl compact>
  83.  * <dt>parentComponent<dd>
  84.  * Defines the Component that is to be the parent of this dialog box.
  85.  * It is used in two ways: the Frame that contains it is used as the Frame
  86.  * parent for the dialog box, and its screen coordinates are used in
  87.  * the placement of the dialog box. In general, the dialog box is placed
  88.  * just below the component. This parameter may be null, in which case
  89.  * a default Frame is used as the parent, and the dialog will be
  90.  * centered on the screen (depending on the L&F).
  91.  * <dt><a name=message>message</a><dd>
  92.  * A descriptive message to be placed in the dialog box.
  93.  * In the most common usage, message is just a String or String constant.
  94.  * However, the type of this parameter is actually Object. It's 
  95.  * interpretation depends on its type:
  96.  * <dl compact>
  97.  * <dt>Object[]<dd>An array of objects is interpreted as a series of
  98.  *                 messages (one per object) arranged in a vertical stack.
  99.  *                 The interpretation is recursive -- each object in the
  100.  *                 array is interpreted according to its type. 
  101.  * <dt>Component<dd>The Component is displayed in the dialog.
  102.  * <dt>Icon<dd>The Icon is wrapped in a JLabel and displayed in the dialog.
  103.  * <dt>others<dd>The object is converted to a String by calling its 
  104.  *               <code>toString</code> method. The result is wrapped in a
  105.  *               JLabel and displayed.
  106.  * </dl>
  107.  * <dt>messageType<dd>Defines the style of the message. The look&feel
  108.  * manager may lay out the dialog differently depending on this value, and
  109.  * will often provide a default icon. The possible values are:
  110.  * <ul>
  111.  * <li>ERROR_MESSAGE
  112.  * <li>INFORMATION_MESSAGE
  113.  * <li>WARNING_MESSAGE
  114.  * <li>QUESTION_MESSAGE
  115.  * <li>PLAIN_MESSAGE
  116.  * </ul>
  117.  * <dt>optionType<dd>Defines the set of option buttons that appear at
  118.  * the bottom of the dialog box:
  119.  * <ul>
  120.  * <li>DEFAULT_OPTION
  121.  * <li>YES_NO_OPTION
  122.  * <li>YES_NO_CANCEL_OPTION
  123.  * <li>OK_CANCEL_OPTION
  124.  * </ul>
  125.  * You aren't limited to this set of option buttons.  You can provide any
  126.  * buttons you want using the options parameter.
  127.  * <dt>options<dd>A more detailed description of the set of option buttons
  128.  * that will appear at the bottom of the dialog box. 
  129.  * The usual value for the options parameter is an array of Strings. But 
  130.  * the parameter type is an array of Objects. A button is created for each
  131.  * object depending on it's type:
  132.  * <dl compact>
  133.  * <dt>Component<dd>The component is added to the button row directly.
  134.  * <dt>Icon<dd>A JButton is created with this as its label.
  135.  * <dt>other<dd>The Object is converted to a string using its
  136.  *              <code>toString</code> method and the result is used to
  137.  *              label a JButton.
  138.  * </dl>
  139.  * <dt>icon<dd>A decorative icon to be placed in the dialog box. A default
  140.  * value for this is determined by the messageType parameter.
  141.  * <dt>title<dd>The title for the dialog box.
  142.  * <dt>initialValue<dd>The default selection (input value).
  143.  * </dl>
  144.  * </blockquote>
  145.  * <p>
  146.  * When the selection is changed, <code>setValue</code> is invoked,
  147.  * which generates a PropertyChangeEvent.
  148.  * <p>
  149.  * If a JOptionPane has configured to all input <code>setWantsInput</code>
  150.  * the bound property JOptionPane.INPUT_VALUE_PROPERTY can also be listened
  151.  * to, to determine when the user has input or selected a value.
  152.  * <p>
  153.  * When one of the <code>showXxxDialog</code> methods returns an integer, 
  154.  * the possible values are:<pre>
  155.  *     YES_OPTION,
  156.  *     NO_OPTION,
  157.  *     CANCEL_OPTION,
  158.  *     OK_OPTION, or
  159.  *     CLOSED_OPTION.
  160.  * </pre>
  161.  * <b>Examples:</b>
  162.  * <dl>
  163.  * <dt>Show an error dialog that displays the message, 'alert':
  164.  * <dd><code>
  165.  * JOptionPane.showMessageDialog(null, "alert", "alert", ERROR_MESSAGE);
  166.  * </code><p>
  167.  * <dt>Show an internal information dialog with the message, 'information':
  168.  * <dd><code>
  169.  * JOptionPane.showInternalMessageDialog(frame, INFORMATION_MESSAGE,<br>
  170.  *             <ul><ul>"information", "information");</ul></ul>
  171.  * </code><p>
  172.  * <dt>Show an information panel with the options yes/no and message 'choose one':
  173.  * <dd><code>JOptionPane.showConfirmDialog(null,
  174.  *             <ul><ul>"choose one", "choose one", YES_NO_OPTION);</ul></ul>
  175.  * </code><p>
  176.  * <dt>Show an internal information dialog with the options yes/no/cancel and
  177.  * message 'please choose one' and title information:
  178.  * <dd><code>JOptionPane.showInternalConfirmDialog(frame,
  179.  *             <ul><ul>"please choose one", "information",</ul></ul>
  180.  *             <ul><ul>YES_NO_CANCEL_OPTION, INFORMATION_MESSAGE);</ul></ul>
  181.  * </code><p>
  182.  * <dt>Show a warning dialog with the options OK, CANCEL, title 'Warning', and
  183.  * message 'Click OK to continue':
  184.  * <dd><code>
  185.  * Object[] options = { "OK", "CANCEL" };<br>
  186.  * JOptionPane.showOptionDialog(null, "Click OK to continue", "Warning",
  187.  *             <ul><ul>DEFAULT_OPTION, WARNING_MESSAGE,</ul></ul>
  188.  *             <ul><ul>null, options, options[0]);</ul></ul>
  189.  * </code><p>
  190.  * <dt>Show a dialog asking the user to type in a String:
  191.  * <dd><code>
  192.  * String inputValue = JOptionPane.showInputDialog("Please input a value");
  193.  * </code><p>
  194.  * <dt>Show a dialog asking the user to select a String:
  195.  * <dd><code>
  196.  * Object[] possibleValues = { "First", "Second", "Third" };<br>
  197.  * Object selectedValue = JOptionPane.showInputDialog(null,
  198.  *             <ul><ul>"Choose one", "Input",</ul></ul>
  199.  *             <ul><ul>JOptionPane.INFORMATION_MESSAGE, null,</ul></ul>
  200.  *             <ul><ul>possibleValues, possibleValues[0]);</ul></ul>
  201.  * </code><p>
  202.  * </dl>
  203.  * <b>Direct Use:</b><br>
  204.  * To create and use an JOptionPane directly, the
  205.  * standard pattern is roughly as follows:
  206.  * <pre>
  207.  *     JOptionPane pane = new JOptionPane(<i>arguments</i>);
  208.  *     pane.set<i>.Xxxx(...); // Configure</i>
  209.  *     JDialog dialog = pane.createDialog(<i>parentComponent, title</i>);
  210.  *     dialog.show();
  211.  *     Object selectedValue = pane.getValue();
  212.  *     if(selectedValue == null)
  213.  *       return CLOSED_OPTION;
  214.  *     <i>//If there is <b>not</b> an array of option buttons:</i>
  215.  *     if(options == null) {
  216.  *       if(selectedValue instanceof Integer)
  217.  *          return ((Integer)selectedValue).intValue();
  218.  *       return CLOSED_OPTION;
  219.  *     }
  220.  *     <i>//If there is an array of option buttons:</i>
  221.  *     for(int counter = 0, maxCounter = options.length;
  222.  *        counter < maxCounter; counter++) {
  223.  *        if(options[counter].equals(selectedValue))
  224.  *        return counter;
  225.  *     }
  226.  *     return CLOSED_OPTION;
  227.  * </pre>
  228.  * <p>
  229.  * For the keyboard keys used by this component in the standard Look and
  230.  * Feel (L&F) renditions, see the
  231.  * <a href="doc-files/Key-Index.html#JOptionPane">JOptionPane</a> key assignments.
  232.  * <p>
  233.  * <strong>Warning:</strong>
  234.  * Serialized objects of this class will not be compatible with 
  235.  * future Swing releases.  The current serialization support is appropriate
  236.  * for short term storage or RMI between applications running the same
  237.  * version of Swing.  A future release of Swing will provide support for
  238.  * long term persistence.
  239.  *
  240.  * @see JInternalFrame
  241.  *
  242.  * @beaninfo
  243.  *      attribute: isContainer true
  244.  *    description: A component which implements standard dialog box controls.
  245.  *
  246.  * @version 1.44 08/28/98
  247.  * @author James Gosling
  248.  * @author Scott Violet
  249.  */
  250. public class JOptionPane extends JComponent implements Accessible
  251. {
  252.     /**
  253.      * @see #getUIClassID
  254.      * @see #readObject
  255.      */
  256.     private static final String uiClassID = "OptionPaneUI";
  257.  
  258.     /**
  259.      * Indicates that the user has not yet selected a value.
  260.      */
  261.     public static final Object      UNINITIALIZED_VALUE = "uninitializedValue";
  262.  
  263.     //
  264.     // Option types
  265.     //
  266.     /** 
  267.      * Type meaning look and feel should not supply any options -- only
  268.      * use the options from the JOptionPane.
  269.      */
  270.     public static final int         DEFAULT_OPTION = -1;
  271.     /** Type used for showConfirmDialog. */
  272.     public static final int         YES_NO_OPTION = 0;
  273.     /** Type used for showConfirmDialog. */
  274.     public static final int         YES_NO_CANCEL_OPTION = 1;
  275.     /** Type used for showConfirmDialog. */
  276.     public static final int         OK_CANCEL_OPTION = 2;
  277.  
  278.     //
  279.     // Return values.
  280.     //
  281.     /** Return value from class method if YES is chosen. */
  282.     public static final int         YES_OPTION = 0;
  283.     /** Return value from class method if NO is chosen. */
  284.     public static final int         NO_OPTION = 1;
  285.     /** Return value from class method if CANCEL is chosen. */
  286.     public static final int         CANCEL_OPTION = 2;
  287.     /** Return value form class method if OK is chosen. */
  288.     public static final int         OK_OPTION = 0;
  289.     /** Return value from class method if user closes window without selecting
  290.      * anything, more than likely this should be treated as either a
  291.      * CANCEL_OPTION or NO_OPTION. */
  292.     public static final int         CLOSED_OPTION = -1;
  293.  
  294.     //
  295.     // Message types. Used by the UI to determine what icon to display,
  296.     // and possibly what behavior to give based on the type.
  297.     //
  298.     /** Used for error messages. */
  299.     public static final int  ERROR_MESSAGE = 0;
  300.     /** Used for information messages. */
  301.     public static final int  INFORMATION_MESSAGE = 1;
  302.     /** Used for warning messages. */
  303.     public static final int  WARNING_MESSAGE = 2;
  304.     /** Used for questions. */
  305.     public static final int  QUESTION_MESSAGE = 3;
  306.     /** No icon is used. */
  307.     public static final int   PLAIN_MESSAGE = -1;
  308.  
  309.     /** Bound property name for icon. */
  310.     public static final String      ICON_PROPERTY = "icon";
  311.     /** Bound property name for message. */
  312.     public static final String      MESSAGE_PROPERTY = "message";
  313.     /** Bounds property name for value. */
  314.     public static final String      VALUE_PROPERTY = "value";
  315.     /** Bounds property namer for option. */
  316.     public static final String      OPTIONS_PROPERTY = "options";
  317.     /** Bounds property name for initialValue. */
  318.     public static final String      INITIAL_VALUE_PROPERTY = "initialValue";
  319.     /** Bounds property name for type. */
  320.     public static final String      MESSAGE_TYPE_PROPERTY = "messageType";
  321.     /** Bound property name for optionType. */
  322.     public static final String      OPTION_TYPE_PROPERTY = "optionType";
  323.     /** Bound property name for selectionValues. */
  324.     public static final String      SELECTION_VALUES_PROPERTY = "selectionValues";
  325.     /** Bound property name for initialSelectionValue. */
  326.     public static final String      INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue";
  327.     /** Bound property name for inputValue. */
  328.     public static final String      INPUT_VALUE_PROPERTY = "inputValue";
  329.     /** Bound property name for wantsInput. */
  330.     public static final String      WANTS_INPUT_PROPERTY = "wantsInput";
  331.  
  332.     /** Icon used in pane. */
  333.     transient protected Icon                  icon;
  334.     /** Message to display. */
  335.     transient protected Object                message;
  336.     /** Options to display to the user. */
  337.     transient protected Object[]              options;
  338.     /** Value that should be initialy selected in options. */
  339.     transient protected Object                initialValue;
  340.     /** Message type. */
  341.     protected int                   messageType;
  342.     /** Option type, one of DEFAULT_OPTION, YES_NO_OPTION,
  343.      * YES_NO_CANCEL_OPTION or OK_CANCEL_OPTION. */
  344.     protected int                   optionType;
  345.     /** Currently selected value, will be a valid option, or
  346.      * UNINITIALIZED_VALUE or null. */
  347.     transient protected Object                value;
  348.     /** Array of values the user can choose from. Look and feel will
  349.      * provide the UI component to choose this from. */
  350.     protected transient Object[]              selectionValues;
  351.     /** Value the user has input. */
  352.     protected transient Object                inputValue;
  353.     /** Initial value to select in selectionValues. */
  354.     protected transient Object                initialSelectionValue;
  355.     /** If true, a UI widget will be provided to the user to get input. */
  356.     protected boolean                         wantsInput;
  357.  
  358.  
  359.     /**
  360.      * Shows a question-message dialog requesting input from the user. The 
  361.      * dialog uses the default frame, which usually means it is centered on 
  362.      * the screen. 
  363.      *
  364.      * @param message the Object to display
  365.      */
  366.     public static String showInputDialog(Object message) {
  367.         return showInputDialog(null, message);
  368.     }
  369.  
  370.     /**
  371.      * Shows a question-message dialog requesting input from the user parented to
  372.      * <code>parentComponent</code>. The dialog is displayed in the Component's
  373.      * frame, and is usually positioned below the Component. 
  374.      *
  375.      * @param parentComponent  the parent Component for the dialog
  376.      * @param message  the Object to display
  377.      */
  378.     public static String showInputDialog(Component parentComponent, Object message){
  379.         return showInputDialog(parentComponent, message, "Input", QUESTION_MESSAGE);
  380.     }
  381.  
  382.     /**
  383.      * Shows a dialog requesting input from the user parented to
  384.      * <code>parentComponent</code> with the dialog having the title
  385.      * <code>title</code> and message type <code>messageType</code>.
  386.      *
  387.      * @param parentComponent  the parent Component for the dialog
  388.      * @param message  the Object to display
  389.      * @param title    the String to display in the dialog title bar
  390.      * @param messageType the type of message that is to be displayed:
  391.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  392.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  393.      */
  394.     public static String showInputDialog(Component parentComponent, Object message,
  395.                                          String title, int messageType) {
  396.         return (String)showInputDialog(parentComponent, message, title,
  397.                                        messageType, null, null, null);
  398.     }
  399.  
  400.     /**
  401.      * Prompts the user for input in a blocking dialog where the
  402.      * initial selection, possible selections, and all other options can
  403.      * be specified. The user will able to choose from
  404.      * <code>selectionValues</code>, where null implies the user can input
  405.      * whatever they wish, usually by means of a JTextField. 
  406.      * <code>initialSelectionValue</code> is the initial value to prompt
  407.      * the user with. It is up to the UI to decide how best to represent
  408.      * the <code>selectionValues</code>, but usually a JComboBox, JList, or
  409.      * JTextField will be used.
  410.      *
  411.      * @param parentComponent  the parent Component for the dialog
  412.      * @param message  the Object to display
  413.      * @param title    the String to display in the dialog title bar
  414.      * @param messageType the type of message to be displayed:
  415.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  416.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  417.      * @param icon     the Icon image to display
  418.      * @param selectionValues an array of Objects that gives the possible
  419.      *                        selections
  420.      * @param initialSelectionValue the value used to initialize the input
  421.      *                              field
  422.      * @return users input, or null meaning the user canceled the input
  423.      */
  424.     public static Object showInputDialog(Component parentComponent, Object message,
  425.                       String title, int messageType, Icon icon,
  426.                       Object[] selectionValues, Object initialSelectionValue) {
  427.         JOptionPane    pane = new JOptionPane(message, messageType,
  428.                                               OK_CANCEL_OPTION, icon,
  429.                                               null, null);
  430.  
  431.         pane.setWantsInput(true);
  432.         pane.setSelectionValues(selectionValues);
  433.         pane.setInitialSelectionValue(initialSelectionValue);
  434.  
  435.         JDialog        dialog = pane.createDialog(parentComponent, title);
  436.  
  437.         pane.selectInitialValue();
  438.         dialog.show();
  439.  
  440.         Object value = pane.getInputValue();
  441.  
  442.         if(value == UNINITIALIZED_VALUE)
  443.             return null;
  444.         return value;
  445.     }
  446.  
  447.     /**
  448.      * Brings up a confirmation dialog -- a modal information-message dialog
  449.      * titled "Confirm".
  450.      *
  451.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  452.      *                  If null, or if the parentComponent has no Frame, a 
  453.      *                  default Frame is used.
  454.      * @param message   The Object to display
  455.      */
  456.     public static void showMessageDialog(Component parentComponent, Object message) {
  457.         showMessageDialog(parentComponent, message, "Message", INFORMATION_MESSAGE);
  458.     }
  459.  
  460.     /**
  461.      * Brings up a dialog that displays a message using a default
  462.      * icon determined by the messageType parameter.
  463.      *
  464.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  465.      *                  If null, or if the parentComponent has no Frame, a 
  466.      *                  default Frame is used.
  467.      * @param message   The Object to display
  468.      * @param title     the title string for the dialog
  469.      * @param messageType the type of message to be displayed:
  470.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  471.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  472.      */
  473.     public static void showMessageDialog(Component parentComponent, Object message,
  474.                                          String title, int messageType) {
  475.         showMessageDialog(parentComponent, message, title, messageType, null);
  476.     }
  477.  
  478.     /**
  479.      * Brings up a dialog displaying a message, specifying all parameters.
  480.      *
  481.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  482.      *                  If null, or if the parentComponent has no Frame, a 
  483.      *                  default Frame is used.
  484.      * @param message   The Object to display
  485.      * @param title     the title string for the dialog
  486.      * @param messageType the type of message to be displayed:
  487.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  488.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  489.      * @param icon      an icon to display in the dialog that helps the user
  490.      *                  identify the kind of message that is being displayed.
  491.      */
  492.     public static void showMessageDialog(Component parentComponent, Object message,
  493.                                          String title, int messageType,
  494.                                          Icon icon){
  495.         showOptionDialog(parentComponent, message, title, DEFAULT_OPTION, 
  496.                          messageType, icon, null, null);
  497.     }
  498.  
  499.     /**
  500.      * Brings up a modal dialog with the options Yes, No and Cancel; with the
  501.      * title, "Select an Option".
  502.      *
  503.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  504.      *                  If null, or if the parentComponent has no Frame, a 
  505.      *                  default Frame is used.
  506.      * @param message   The Object to display
  507.      * @return an int indicating the option selected by the user
  508.      */
  509.     public static int showConfirmDialog(Component parentComponent, Object message) {
  510.         return showConfirmDialog(parentComponent, message, "Select an Option",
  511.                                  YES_NO_CANCEL_OPTION);
  512.     }
  513.  
  514.     /**
  515.      * Brings up a modal dialog where the number of choices is determined
  516.      * by the <code>optionType</code> parameter.
  517.      * 
  518.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  519.      *                  If null, or if the parentComponent has no Frame, a 
  520.      *                  default Frame is used.
  521.      * @param message   The Object to display
  522.      * @param title     the title string for the dialog
  523.      * @param optionType an int designating the options available on the dialog:
  524.      *                   YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  525.      * @return an int indicating the option selected by the user
  526.      */
  527.     public static int showConfirmDialog(Component parentComponent, Object message,
  528.                                         String title, int optionType) {
  529.         return showConfirmDialog(parentComponent, message, title, optionType,
  530.                                  QUESTION_MESSAGE);
  531.     }
  532.  
  533.     /**
  534.      * Brings up a modal dialog where the number of choices is determined
  535.      * by the <code>optionType</code> parameter, where the <code>messageType</code>
  536.      * parameter determines the icon to display.
  537.      * The <code>messageType</code> parameter is primarily used to supply
  538.      * a default icon from the look and feel.
  539.      *
  540.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  541.      *                  If null, or if the parentComponent has no Frame, a 
  542.      *                  default Frame is used.
  543.      * @param message   The Object to display
  544.      * @param title     the title string for the dialog
  545.      * @param optionType an int designating the options available on the dialog:
  546.      *                   YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  547.      * @param messageType an int designating the kind of message this is, 
  548.      *                    primarily used to determine the icon from the pluggable
  549.      *                    look and feel: ERROR_MESSAGE, INFORMATION_MESSAGE, 
  550.      *                    WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE.
  551.      * @return an int indicating the option selected by the user
  552.      */
  553.     public static int showConfirmDialog(Component parentComponent, Object message,
  554.                                         String title, int optionType,
  555.                                         int messageType) {
  556.         return showConfirmDialog(parentComponent, message, title, optionType,
  557.                                 messageType, null);
  558.     }
  559.  
  560.     /**
  561.      * Brings up a modal dialog with a specified icon, where the number of 
  562.      * choices is determined by the <code>optionType</code> parameter.
  563.      * The <code>messageType</code> parameter is primarily used to supply
  564.      * a default icon from the look and feel.
  565.      *
  566.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  567.      *                  If null, or if the parentComponent has no Frame, a 
  568.      *                  default Frame is used.
  569.      * @param message   The Object to display
  570.      * @param title     the title string for the dialog
  571.      * @param optionType an int designating the options available on the dialog:
  572.      *                   YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  573.      * @param messageType an int designating the kind of message this is, 
  574.      *                    primarily used to determine the icon from the pluggable
  575.      *                    look and feel: ERROR_MESSAGE, INFORMATION_MESSAGE, 
  576.      *                    WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE.
  577.      * @param icon      the icon to display in the dialog
  578.      * @return an int indicating the option selected by the user
  579.      */
  580.     public static int showConfirmDialog(Component parentComponent, Object message,
  581.                                         String title, int optionType,
  582.                                         int messageType, Icon icon) {
  583.         return showOptionDialog(parentComponent, message, title, optionType,
  584.                                 messageType, icon, null, null);
  585.     }
  586.  
  587.     /**
  588.      * Brings up a modal dialog with a specified icon, where the initial
  589.      * choice is dermined by the <code>initialValue</code> parameter and
  590.      * the number of choices is determined by the <code>optionType</code> 
  591.      * parameter.
  592.      * <p>
  593.      * If <code>optionType</code> is YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  594.      * and the <code>options</code> parameter is null, then the options are
  595.      * supplied by the look and feel. 
  596.      * <p>
  597.      * The <code>messageType</code> parameter is primarily used to supply
  598.      * a default icon from the look and feel.
  599.      *
  600.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  601.      *                  If null, or if the parentComponent has no Frame, a 
  602.      *                  default Frame is used.
  603.      * @param message   The Object to display
  604.      * @param title     the title string for the dialog
  605.      * @param optionType an int designating the options available on the dialog:
  606.      *                   YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  607.      * @param messageType an int designating the kind of message this is, 
  608.      *                    primarily used to determine the icon from the pluggable
  609.      *                    look and feel: ERROR_MESSAGE, INFORMATION_MESSAGE, 
  610.      *                    WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE.
  611.      * @param icon      the icon to display in the dialog
  612.      * @param options   an array of objects indicating the possible choices
  613.      *                  the user can make. If the objects are components, they
  614.      *                  are rendered properly. Non-String objects are
  615.      *                  rendered using their <code>toString</code> methods.
  616.      *                  If this parameter is null, the options are determined
  617.      *                  by the look and feel.
  618.      * @param initialValue the object that represents the default selection
  619.      *                     for the dialog
  620.      * @return an int indicating the option chosen by the user, 
  621.      *         or CLOSED_OPTION if the user closed the Dialog
  622.      */
  623.     public static int showOptionDialog(Component parentComponent, Object message,
  624.                                        String title, int optionType,
  625.                                        int messageType, Icon icon,
  626.                                        Object[] options, Object initialValue) {
  627.         JOptionPane             pane = new JOptionPane(message, messageType,
  628.                                                        optionType, icon,
  629.                                                        options, initialValue);
  630.  
  631.         pane.setInitialValue(initialValue);
  632.  
  633.         JDialog         dialog = pane.createDialog(parentComponent, title);
  634.  
  635.         pane.selectInitialValue();
  636.         dialog.show();
  637.  
  638.         Object        selectedValue = pane.getValue();
  639.  
  640.         if(selectedValue == null)
  641.             return CLOSED_OPTION;
  642.         if(options == null) {
  643.             if(selectedValue instanceof Integer)
  644.                 return ((Integer)selectedValue).intValue();
  645.             return CLOSED_OPTION;
  646.         }
  647.         for(int counter = 0, maxCounter = options.length;
  648.             counter < maxCounter; counter++) {
  649.             if(options[counter].equals(selectedValue))
  650.                 return counter;
  651.         }
  652.         return CLOSED_OPTION;
  653.     }
  654.  
  655.     /**
  656.      * Creates and returns a new JDialog wrapping <code>this</code>
  657.      * centered on the <code>parentComponent</code> in the 
  658.      * <code>parentComponent</code>'s frame.
  659.      * <code>title</code> is the title of the returned dialog.
  660.      * The returned JDialog will be set up such that once it is closed,
  661.      * or the user clicks on the OK button, the dialog will be disposed
  662.      * and closed.
  663.      *Re if the parentComponent has no Frame, a 
  664.      *                  default Frame is used.
  665.      * @param title     the title string for the dialog
  666.      * @return a new JDialog containing this instance
  667.      */
  668.     public JDialog createDialog(Component parentComponent, String title) {
  669.         Frame         frame = JOptionPane.getFrameForComponent(parentComponent);
  670.         final JDialog dialog;
  671.  
  672.         String osName = System.getProperty("os.name");
  673.         final boolean solarisWorkaround = (osName != null && 
  674.                                            osName.indexOf("Solaris") != -1);
  675.        
  676.         if (solarisWorkaround) {
  677.             // Workaround for bug in Solaris where modal dialog
  678.             // disposal causes segv (4137962); this workaround exposes
  679.             // bugs on win32, so only do it on Solaris
  680.             //
  681.             dialog = SwingUtilities.getRecycledModalDialog(frame, title);
  682.  
  683.         } else {
  684.             dialog = new JDialog(frame, title, true);
  685.         }
  686.         Container             contentPane = dialog.getContentPane();
  687.  
  688.         contentPane.setLayout(new BorderLayout());
  689.         contentPane.add(this, BorderLayout.CENTER);
  690.         dialog.pack();
  691.         dialog.setLocationRelativeTo(parentComponent);
  692.         dialog.addWindowListener(new WindowAdapter() {
  693.             boolean gotFocus = false;
  694.             public void windowClosing(WindowEvent we) {
  695.                 setValue(null);
  696.             }
  697.             public void windowActivated(WindowEvent we) {
  698.                 // Once window gets focus, set initial focus
  699.                 if (!gotFocus) {
  700.                     selectInitialValue();
  701.                     gotFocus = true;
  702.                 }
  703.             }
  704.         });
  705.         addPropertyChangeListener(new PropertyChangeListener() {
  706.             public void propertyChange(PropertyChangeEvent event) {
  707.                 if(dialog.isVisible() && event.getSource() == JOptionPane.this &&
  708.                    (event.getPropertyName().equals(VALUE_PROPERTY) ||
  709.                     event.getPropertyName().equals(INPUT_VALUE_PROPERTY))) {
  710.                     dialog.setVisible(false);
  711.                     if (solarisWorkaround) {
  712.                         // Workaround for bug in Solaris where modal dialog
  713.                        // disposal causes segv (4137962)
  714.                         SwingUtilities.recycleModalDialog(dialog);
  715.                     } else {
  716.                         dialog.dispose();
  717.                     }
  718.                 }
  719.             }
  720.         });
  721.         return dialog;
  722.     }
  723.         
  724.  
  725.     /**
  726.      * Brings up an internal confirmation dialog panel. The dialog
  727.      * is a modal information-message dialog titled "Message".
  728.      *
  729.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  730.      *                  If null, or if the parentComponent has no Frame, a 
  731.      *                  default Frame is used.
  732.      * @param message   The object to display
  733.      */
  734.     public static void showInternalMessageDialog(Component parentComponent,
  735.                                                  Object message) {
  736.         showInternalMessageDialog(parentComponent, message, "Message",
  737.                                   INFORMATION_MESSAGE);
  738.     }
  739.  
  740.     /** 
  741.      * Brings up an internal dialog panel that displays a message 
  742.      * using a default icon determined by the messageType parameter.
  743.      *
  744.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  745.      *                  If null, or if the parentComponent has no Frame, a 
  746.      *                  default Frame is used.
  747.      * @param message   The Object to display
  748.      * @param title     the title string for the dialog
  749.      * @param messageType the type of message to be displayed:
  750.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  751.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  752.      */
  753.     public static void showInternalMessageDialog(Component parentComponent,
  754.                                                  Object message, String title,
  755.                                                  int messageType) {
  756.         showInternalMessageDialog(parentComponent, message, title, messageType,null);
  757.     }
  758.  
  759.     /**
  760.      * Brings up an internal dialog panel displaying a message, 
  761.      * specifying all parameters.
  762.      *
  763.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  764.      *                  If null, or if the parentComponent has no Frame, a 
  765.      *                  default Frame is used.
  766.      * @param message   The Object to display
  767.      * @param title     the title string for the dialog
  768.      * @param messageType the type of message to be displayed:
  769.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  770.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  771.      * @param icon      an icon to display in the dialog that helps the user
  772.      *                  identify the kind of message that is being displayed.
  773.      */
  774.     public static void showInternalMessageDialog(Component parentComponent,
  775.                                          Object message,
  776.                                          String title, int messageType,
  777.                                          Icon icon){
  778.         showInternalOptionDialog(parentComponent, message, title, DEFAULT_OPTION,
  779.                                  messageType, icon, null, null);
  780.     }
  781.  
  782.     /**
  783.      * Brings up an internal dialog panel with the options Yes, No 
  784.      * and Cancel; with the title, "Select an Option".
  785.      *
  786.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  787.      *                  If null, or if the parentComponent has no Frame, a 
  788.      *                  default Frame is used.
  789.      * @param message   The Object to display
  790.      * @return an int indicating the option selected by the user
  791.      */
  792.     public static int showInternalConfirmDialog(Component parentComponent,
  793.                                                 Object message) {
  794.         return showInternalConfirmDialog(parentComponent, message,
  795.                                   "Select an Option", YES_NO_CANCEL_OPTION);
  796.     }
  797.  
  798.     /**
  799.      * Brings up a internal dialog panel where the number of choices 
  800.      * is determined by the <code>optionType</code> parameter.
  801.      * 
  802.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  803.      *                  If null, or if the parentComponent has no Frame, a 
  804.      *                  default Frame is used.
  805.      * @param message   The object to display in the dialog. A Component object
  806.      *                  is rendered as a Component. A String object is rendered
  807.      *                  as a string. Other objects are converted to a String
  808.      *                  using the <code>toString</code> method.
  809.      * @param title     the title string for the dialog
  810.      * @param optionType an int designating the options available on the dialog:
  811.      *                   YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  812.      * @return an int indicating the option selected by the user
  813.      */
  814.     public static int showInternalConfirmDialog(Component parentComponent,
  815.                                                 Object message, String title,
  816.                                                 int optionType) {
  817.         return showInternalConfirmDialog(parentComponent, message, title, optionType,
  818.                                          QUESTION_MESSAGE);
  819.     }
  820.  
  821.     /**
  822.      * Brings up an internal dialog panel where the number of choices
  823.      * is determined by the <code>optionType</code> parameter, where
  824.      * the <code>messageType</code> parameter determines the icon to display.
  825.      * The <code>messageType</code> parameter is primarily used to supply
  826.      * a default icon from the look and feel.
  827.      *
  828.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  829.      *                  If null, or if the parentComponent has no Frame, a 
  830.      *                  default Frame is used.
  831.      * @param message   The object to display in the dialog. A Component object
  832.      *                  is rendered as a Component. A String object is rendered
  833.      *                  as a string. Other objects are converted to a String
  834.      *                  using the <code>toString</code> method.
  835.      * @param title     the title string for the dialog
  836.      * @param optionType an int designating the options available on the dialog:
  837.      *                   YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  838.      * @param messageType an int designating the kind of message this is, 
  839.      *                    primarily used to determine the icon from the pluggable
  840.      *                    look and feel: ERROR_MESSAGE, INFORMATION_MESSAGE, 
  841.      *                    WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE.
  842.      * @return an int indicating the option selected by the user
  843.      */
  844.     public static int showInternalConfirmDialog(Component parentComponent, 
  845.                                         Object message,
  846.                                         String title, int optionType,
  847.                                         int messageType) {
  848.         return showInternalConfirmDialog(parentComponent, message, title, optionType,
  849.                                          messageType, null);
  850.     }
  851.  
  852.     /**
  853.      * Brings up an internal dialog panel with a specified icon, where
  854.      * the number of choices is determined by the <code>optionType</code>
  855.      * parameter. 
  856.      * The <code>messageType</code> parameter is primarily used to supply
  857.      * a default icon from the look and feel.
  858.      *
  859.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  860.      *                  If null, or if the parentComponent has no Frame, a 
  861.      *                  default Frame is used.
  862.      * @param message   The object to display in the dialog. A Component object
  863.      *                  is rendered as a Component. A String object is rendered
  864.      *                  as a string. Other objects are converted to a String
  865.      *                  using the <code>toString</code> method.
  866.      * @param title     the title string for the dialog
  867.      * @param optionType an int designating the options available on the dialog:
  868.      *                   YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  869.      * @param messageType an int designating the kind of message this is, 
  870.      *                    primarily used to determine the icon from the pluggable
  871.      *                    look and feel: ERROR_MESSAGE, INFORMATION_MESSAGE, 
  872.      *                    WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE.
  873.      * @param icon      the icon to display in the dialog
  874.      * @return an int indicating the option selected by the user
  875.      */
  876.     public static int showInternalConfirmDialog(Component parentComponent,
  877.                                         Object message,
  878.                                         String title, int optionType,
  879.                                         int messageType, Icon icon) {
  880.         return showInternalOptionDialog(parentComponent, message, title, optionType,
  881.                                         messageType, icon, null, null);
  882.     }
  883.  
  884.     /**
  885.      * Brings up an internal dialog panel with a specified icon, where
  886.      * the initial choice is dermined by the <code>initialValue</code>
  887.      * parameter and the number of choices is determined by the 
  888.      * <code>optionType</code> parameter.
  889.      * <p>
  890.      * If <code>optionType</code> is YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  891.      * and the <code>options</code> parameter is null, then the options are
  892.      * supplied by the look and feel. 
  893.      * <p>
  894.      * The <code>messageType</code> parameter is primarily used to supply
  895.      * a default icon from the look and feel.
  896.      *
  897.      * @param parentComponent Determines the Frame in which the dialog is displayed. 
  898.      *                  If null, or if the parentComponent has no Frame, a 
  899.      *                  default Frame is used.
  900.      * @param message   The object to display in the dialog. A Component object
  901.      *                  is rendered as a Component. A String object is rendered
  902.      *                  as a string. Other objects are converted to a String
  903.      *                  using the <code>toString</code> method.
  904.      * @param title     the title string for the dialog
  905.      * @param optionType an int designating the options available on the dialog:
  906.      *                   YES_NO_OPTION, or YES_NO_CANCEL_OPTION
  907.      * @param messageType an int designating the kind of message this is, 
  908.      *                    primarily used to determine the icon from the pluggable
  909.      *                    look and feel: ERROR_MESSAGE, INFORMATION_MESSAGE, 
  910.      *                    WARNING_MESSAGE, QUESTION_MESSAGE, or PLAIN_MESSAGE.
  911.      * @param icon      the icon to display in the dialog
  912.      * @param options   an array of objects indicating the possible choices
  913.      *                  the user can make. If the objects are components, they
  914.      *                  are rendered properly. Non-String objects are
  915.      *                  rendered using their <code>toString</code> methods.
  916.      *                  If this parameter is null, the options are determined
  917.      *                  by the look and feel.
  918.      * @param initialValue the object that represents the default selection
  919.      *                     for the dialog
  920.      * @return an int indicating the option chosen by the user, 
  921.      *         or CLOSED_OPTION if the user closed the Dialog
  922.      */
  923.     public static int showInternalOptionDialog(Component parentComponent,
  924.                                        Object message,
  925.                                        String title, int optionType,
  926.                                        int messageType, Icon icon,
  927.                                        Object[] options, Object initialValue) {
  928.         JOptionPane             pane = new JOptionPane(message, messageType,
  929.                                                        optionType, icon,
  930.                                                        options, initialValue);
  931.  
  932.         pane.setInitialValue(initialValue);
  933.  
  934.         JInternalFrame   dialog = pane.createInternalFrame(parentComponent, title);
  935.  
  936.         pane.selectInitialValue();
  937.         dialog.startModal();
  938.  
  939.         Object        selectedValue = pane.getValue();
  940.  
  941.         if(selectedValue == null)
  942.             return CLOSED_OPTION;
  943.         if(options == null) {
  944.             if(selectedValue instanceof Integer)
  945.                 return ((Integer)selectedValue).intValue();
  946.             return CLOSED_OPTION;
  947.         }
  948.         for(int counter = 0, maxCounter = options.length;
  949.             counter < maxCounter; counter++) {
  950.             if(options[counter].equals(selectedValue))
  951.                 return counter;
  952.         }
  953.         return CLOSED_OPTION;
  954.     }
  955.  
  956.     /**
  957.      * Shows an internal question-message dialog requesting input from
  958.      * the user parented to  <code>parentComponent</code>. The dialog
  959.      * is displayed in the Component's frame, and is usually positioned
  960.      * below the Component. 
  961.      *
  962.      * @param parentComponent  the parent Component for the dialog
  963.      * @param message  the Object to display
  964.      */
  965.     public static String showInternalInputDialog(Component parentComponent,
  966.                                                  Object message) {
  967.         return showInternalInputDialog(parentComponent, message, "Input",
  968.                                        QUESTION_MESSAGE);
  969.     }
  970.  
  971.     /**
  972.      * Shows an internal dialog requesting input from the user parented
  973.      * to <code>parentComponent</code> with the dialog having the title
  974.      * <code>title</code> and message type <code>messageType</code>.
  975.      *
  976.      * @param parentComponent  the parent Component for the dialog
  977.      * @param message  the Object to display
  978.      * @param title    the String to display in the dialog title bar
  979.      * @param messageType the type of message that is to be displayed:
  980.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  981.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  982.      */
  983.     public static String showInternalInputDialog(Component parentComponent,
  984.                              Object message, String title, int messageType) {
  985.         return (String)showInternalInputDialog(parentComponent, message, title,
  986.                                        messageType, null, null, null);
  987.     }
  988.  
  989.     /**
  990.      * Prompts the user for input in a blocking internal dialog where
  991.      * the initial selection, possible selections, and all other 
  992.      * options can be specified. The user will able to choose from
  993.      * <code>selectionValues</code>, where null implies the user can input
  994.      * whatever they wish, usually by means of a JTextField. 
  995.      * <code>initialSelectionValue</code> is the initial value to prompt
  996.      * the user with. It is up to the UI to decide how best to represent
  997.      * the <code>selectionValues</code>, but usually a JComboBox, JList, or
  998.      * JTextField will be used.
  999.      *
  1000.      * @param parentComponent  the parent Component for the dialog
  1001.      * @param message  the Object to display
  1002.      * @param title    the String to display in the dialog title bar
  1003.      * @param messageType the type of message to be displayed:
  1004.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  1005.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  1006.      * @param icon     the Icon image to display
  1007.      * @param selectionValues an array of Objects that gives the possible
  1008.      *                        selections
  1009.      * @param initialSelectionValue the value used to initialize the input
  1010.      *                              field
  1011.      * @return users input, or null meaning the user canceled the input
  1012.      */
  1013.     public static Object showInternalInputDialog(Component parentComponent,
  1014.                       Object message, String title, int messageType, Icon icon,
  1015.                       Object[] selectionValues, Object initialSelectionValue) {
  1016.         JOptionPane             pane = new JOptionPane(message, messageType,
  1017.                                                        OK_CANCEL_OPTION, icon,
  1018.                                                        null, null);
  1019.  
  1020.         pane.setWantsInput(true);
  1021.         pane.setSelectionValues(selectionValues);
  1022.         pane.setInitialSelectionValue(initialSelectionValue);
  1023.  
  1024.         JInternalFrame   dialog = pane.createInternalFrame(parentComponent, title);
  1025.  
  1026.         pane.selectInitialValue();
  1027.         dialog.startModal();
  1028.  
  1029.         Object value = pane.getInputValue();
  1030.  
  1031.         if(value == UNINITIALIZED_VALUE)
  1032.             return null;
  1033.         return (String)value;
  1034.     }
  1035.  
  1036.     /**
  1037.      * Creates and returns an instance of JInternalFrame. 
  1038.      * The internal frame is created with the specified title,
  1039.      * and wrapping the JOptionPane. The returned JInternalFrame is
  1040.      * added to the JDesktopPane ancestor of parentComponent, or components
  1041.      * parent if one its ancestors isn't a JDesktopPane, or if parentComponent
  1042.      * doesn't have a parent then a <code>RuntimeException</code> is thrown.
  1043.      *
  1044.      * @param parentComponent  the parent Component for the internal frame
  1045.      * @param title    the String to display in the frame's title bar
  1046.      * @return a JInternalFrame containing a JOptionPane
  1047.      */
  1048.     public JInternalFrame createInternalFrame(Component parentComponent,
  1049.                                  String title) {
  1050.         Container          parent = JOptionPane.
  1051.                                     getDesktopPaneForComponent(parentComponent);
  1052.  
  1053.         if(parent == null && (parentComponent == null || 
  1054.                               (parent = parentComponent.getParent()) == null))
  1055.             throw new RuntimeException("JOptionPane: parentComponent does not have a valid parent");
  1056.  
  1057.         final JInternalFrame  iFrame = new JInternalFrame(title, true, false,
  1058.                                                            false, false);
  1059.         addPropertyChangeListener(new PropertyChangeListener() {
  1060.             public void propertyChange(PropertyChangeEvent event) {
  1061.                 if(iFrame.isVisible() && event.getSource() == JOptionPane.this &&
  1062.                    (event.getPropertyName().equals(VALUE_PROPERTY) ||
  1063.                     event.getPropertyName().equals(INPUT_VALUE_PROPERTY))) {
  1064.                     try {
  1065.                         iFrame.setClosed(true);
  1066.                     } catch (java.beans.PropertyVetoException e) {}
  1067.                     iFrame.setVisible(false);
  1068.                     iFrame.stopModal();
  1069.                 }
  1070.             }
  1071.         });
  1072.         iFrame.getContentPane().add(this, BorderLayout.CENTER);
  1073.  
  1074.         if(parent instanceof JDesktopPane) {
  1075.             parent.add(iFrame, JLayeredPane.MODAL_LAYER);
  1076.         } else {
  1077.             parent.add(iFrame, BorderLayout.CENTER);
  1078.         }
  1079.  
  1080.         Dimension            iFrameSize = iFrame.getPreferredSize();
  1081.         Dimension            rootSize = parent.getSize();
  1082.  
  1083.         iFrame.setBounds((rootSize.width - iFrameSize.width) / 2,
  1084.                          (rootSize.height - iFrameSize.height) / 2,
  1085.                          iFrameSize.width, iFrameSize.height);
  1086.         parent.validate();
  1087.         try {
  1088.             iFrame.setSelected(true);
  1089.         } catch (java.beans.PropertyVetoException e) {}
  1090.         return iFrame;
  1091.     }
  1092.  
  1093.     /**
  1094.      * Returns the specified component's Frame.
  1095.      * 
  1096.      * @param parentComponent the Component to check for a Frame
  1097.      * @return the Frame that contains the component, or the default
  1098.      *         frame if the component is null, or does not have a valid 
  1099.      *         Frame parent
  1100.      */
  1101.     public static Frame getFrameForComponent(Component parentComponent) {
  1102.         if (parentComponent == null)
  1103.             return getRootFrame();
  1104.         if (parentComponent instanceof Frame)
  1105.             return (Frame)parentComponent;
  1106.         return JOptionPane.getFrameForComponent(parentComponent.getParent());
  1107.     }
  1108.  
  1109.     /**
  1110.      * Returns the specified component's desktop pane.
  1111.      * 
  1112.      * @param parentComponent the Component to check for a desktop
  1113.      * @return the JDesktopPane that contains the component, or null
  1114.      *         if the component is null or does not have an ancestor 
  1115.      *         that is a JInternalFrame
  1116.      */
  1117.     public static JDesktopPane getDesktopPaneForComponent(Component parentComponent) {
  1118.         if(parentComponent == null)
  1119.             return null;
  1120.         if(parentComponent instanceof JDesktopPane)
  1121.             return (JDesktopPane)parentComponent;
  1122.         return getDesktopPaneForComponent(parentComponent.getParent());
  1123.     }
  1124.  
  1125.     private static final Object sharedFrameKey = JOptionPane.class;
  1126.  
  1127.     /**
  1128.      * Sets the frame to use for class methods in which a frame is
  1129.      * not provided.
  1130.      *
  1131.      * @param newRootFrame the default Frame to use
  1132.      */
  1133.     public static void setRootFrame(Frame newRootFrame) {
  1134.         if (newRootFrame != null) {
  1135.             SwingUtilities.appContextPut(sharedFrameKey, newRootFrame);
  1136.         } else {
  1137.             SwingUtilities.appContextRemove(sharedFrameKey);
  1138.         }
  1139.     }
  1140.  
  1141.     /**
  1142.      * Returns the Frame to use for the class methods in which a frame
  1143.      * is not provided.
  1144.      *
  1145.      * @return the default Frame to use
  1146.      */
  1147.     public static Frame getRootFrame() {
  1148.         Frame sharedFrame = 
  1149.             (Frame)SwingUtilities.appContextGet(sharedFrameKey);
  1150.         if (sharedFrame == null) {
  1151.             sharedFrame = SwingUtilities.getSharedOwnerFrame();
  1152.             SwingUtilities.appContextPut(sharedFrameKey, sharedFrame);
  1153.         }
  1154.         return sharedFrame;
  1155.     }
  1156.  
  1157.     /**
  1158.      * Creates a JOptionPane with a test message.
  1159.      */
  1160.     public JOptionPane() {
  1161.         this("JOptionPane message");
  1162.     }
  1163.  
  1164.     /**
  1165.      * Creates a instance of JOptionPane to display a message using the 
  1166.      * plain-message message type and the default options delivered by
  1167.      * the UI.
  1168.      *
  1169.      * @param message the Object to display
  1170.      */
  1171.     public JOptionPane(Object message) {
  1172.         this(message, PLAIN_MESSAGE);
  1173.     }
  1174.  
  1175.     /**
  1176.      * Creates an instance of JOptionPane to display a message
  1177.      * with the specified message type and the default options,
  1178.      *
  1179.      * @param message the Object to display
  1180.      * @param messageType the type of message to be displayed:
  1181.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  1182.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  1183.      */
  1184.     public JOptionPane(Object message, int messageType) {
  1185.         this(message, messageType, DEFAULT_OPTION);
  1186.     }
  1187.  
  1188.     /**
  1189.      * Creates an instance of JOptionPane to display a message
  1190.      * with the specified message type and options.
  1191.      *
  1192.      * @param message the Object to display
  1193.      * @param messageType the type of message to be displayed:
  1194.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  1195.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  1196.      * @param optionType the options to display in the pane:
  1197.      *                   DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION
  1198.      *                   OK_CANCEL_OPTION
  1199.      */
  1200.     public JOptionPane(Object message, int messageType, int optionType) {
  1201.         this(message, messageType, optionType, null);
  1202.     }
  1203.  
  1204.     /**
  1205.      * Creates an instance of JOptionPane to display a message
  1206.      * with the specified message type, options, and icon.
  1207.      *
  1208.      * @param message the Object to display
  1209.      * @param messageType the type of message to be displayed:
  1210.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  1211.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  1212.      * @param optionType the options to display in the pane:
  1213.      *                   DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION
  1214.      *                   OK_CANCEL_OPTION
  1215.      * @param icon the Icon image to display
  1216.      */
  1217.     public JOptionPane(Object message, int messageType, int optionType,
  1218.                        Icon icon) {
  1219.         this(message, messageType, optionType, icon, null);
  1220.     }
  1221.  
  1222.     /**
  1223.      * Creates an instance of JOptionPane to display a message
  1224.      * with the specified message type, icon, and options.
  1225.      * None of the options is initially selected.
  1226.      * <p>
  1227.      * The options objects should contain either instances of Components,
  1228.      * (which are added directly) or Strings (which are wrapped in a 
  1229.      * JButton). If you provide Components, you must ensure that when the
  1230.      * Component is clicked it messages <code>setValue</code> in the
  1231.      * created JOptionPane.
  1232.      *
  1233.      * @param message the Object to display
  1234.      * @param messageType the type of message to be displayed:
  1235.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  1236.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  1237.      * @param optionType the options to display in the pane:
  1238.      *                   DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION
  1239.      *                   OK_CANCEL_OPTION. Only meaningful if the 
  1240.      *                   <code>options</code> parameter is null.
  1241.      * @param icon the Icon image to display
  1242.      * @param options  the choices the user can select
  1243.      */
  1244.     public JOptionPane(Object message, int messageType, int optionType,
  1245.                        Icon icon, Object[] options) {
  1246.         this(message, messageType, optionType, icon, options, null);
  1247.     }
  1248.  
  1249.     /**
  1250.      * Creates an instance of JOptionPane to display a message
  1251.      * with the specified message type, icon, and options, with the 
  1252.      * inititially-selected option specified.
  1253.      *
  1254.      * @param message the Object to display
  1255.      * @param messageType the type of message to be displayed:
  1256.      *                    ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  1257.      *                    QUESTION_MESSAGE, or PLAIN_MESSAGE.
  1258.      * @param optionType the options to display in the pane:
  1259.      *                   DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION
  1260.      *                   OK_CANCEL_OPTION. Only meaningful if the
  1261.      *                   <code>options</code> parameter is null.
  1262.      * @param icon the Icon image to display
  1263.      * @param options  the choices the user can select
  1264.      * @param initialValue the choice that is initially selected
  1265.      */
  1266.     public JOptionPane(Object message, int messageType, int optionType,
  1267.                        Icon icon, Object[] options, Object initialValue) {
  1268.         this.message = message;
  1269.         this.options = options;
  1270.         this.initialValue = initialValue;
  1271.         this.icon = icon;
  1272.         setMessageType(messageType);
  1273.         setOptionType(optionType);
  1274.         value = UNINITIALIZED_VALUE;
  1275.         inputValue = UNINITIALIZED_VALUE;
  1276.         updateUI();
  1277.     }
  1278.  
  1279.     /**
  1280.      * Sets the UI object which implements the L&F for this component.
  1281.      *
  1282.      * @param ui  the OptionPaneUI L&F object
  1283.      * @see UIDefaults#getUI
  1284.      * @beaninfo
  1285.      *       bound: true
  1286.      *      hidden: true
  1287.      * description: The UI object that implements the optionpane's LookAndFeel
  1288.      */
  1289.     public void setUI(OptionPaneUI ui) {
  1290.         if ((OptionPaneUI)this.ui != ui) {
  1291.             super.setUI(ui);
  1292.             invalidate();
  1293.         }
  1294.     }
  1295.  
  1296.     /**
  1297.      * Returns the UI object which implements the L&F for this component.
  1298.      *
  1299.      * @return the OptionPaneUI object
  1300.      */
  1301.     public OptionPaneUI getUI() {
  1302.         return (OptionPaneUI)ui;
  1303.     }
  1304.  
  1305.     /**
  1306.      * Notification from the UIManager that the L&F has changed. 
  1307.      * Replaces the current UI object with the latest version from the 
  1308.      * UIManager.
  1309.      *
  1310.      * @see JComponent#updateUI
  1311.      */
  1312.     public void updateUI() {
  1313.         setUI((OptionPaneUI)UIManager.getUI(this));
  1314.     }
  1315.  
  1316.  
  1317.     /**
  1318.      * Returns the name of the UI class that implements the
  1319.      * L&F for this component.
  1320.      *
  1321.      * @return "OptionPaneUI"
  1322.      * @see JComponent#getUIClassID
  1323.      * @see UIDefaults#getUI
  1324.      */
  1325.     public String getUIClassID() {
  1326.         return uiClassID;
  1327.     }
  1328.  
  1329.  
  1330.     /**
  1331.      * Sets the option pane's message-object.
  1332.      * @param newMessage the Object to display
  1333.      * @see #getMessage
  1334.      *
  1335.      * @beaninfo
  1336.      *   preferred: true
  1337.      *   bound: true
  1338.      * description: The optionpane's message object.
  1339.      */
  1340.     public void setMessage(Object newMessage) {
  1341.         Object           oldMessage = message;
  1342.  
  1343.         message = newMessage;
  1344.         firePropertyChange(MESSAGE_PROPERTY, oldMessage, message);
  1345.     }
  1346.  
  1347.     /**
  1348.      * Returns the message-object this pane displays.
  1349.      * @see #setMessage
  1350.      *
  1351.      * @return the Object that is displayed
  1352.      */
  1353.     public Object getMessage() {
  1354.         return message;
  1355.     }
  1356.  
  1357.     /**
  1358.      * Sets the icon to display. If non-null, the look and feel 
  1359.      * does not provide an icon.
  1360.      * @param icon the Icon to display
  1361.      *
  1362.      * @see #getIcon
  1363.      * @beaninfo
  1364.      *   preferred: true
  1365.      *       bound: true
  1366.      * description: The option pane's type icon.
  1367.      */
  1368.     public void setIcon(Icon newIcon) {
  1369.         Object              oldIcon = icon;
  1370.  
  1371.         icon = newIcon;
  1372.         firePropertyChange(ICON_PROPERTY, oldIcon, icon);
  1373.     }
  1374.  
  1375.     /**
  1376.      * Returns the icon this pane displays.
  1377.      * @return the Icon that is displayed
  1378.      *
  1379.      * @see #setIcon
  1380.      */
  1381.     public Icon getIcon() {
  1382.         return icon;
  1383.     }
  1384.  
  1385.     /**
  1386.      * Sets the value the user has chosen. 
  1387.      * @param newValue  the chosen value
  1388.      *
  1389.      * @see #getValue
  1390.      * @beaninfo
  1391.      *   preferred: true
  1392.      *       bound: true
  1393.      * description: The option pane's value object.
  1394.      */
  1395.     public void setValue(Object newValue) {
  1396.         Object               oldValue = value;
  1397.  
  1398.         value = newValue;
  1399.         firePropertyChange(VALUE_PROPERTY, oldValue, value);
  1400.     }
  1401.  
  1402.     /**
  1403.      * Returns the value the user has selected. UNINITIALIZED_VALUE
  1404.      * implies the user has not yet made a choice, null means the
  1405.      * user closed the window with out chosing anything. Otherwise
  1406.      * the returned value will be one of the options defined in this
  1407.      * object.
  1408.      *
  1409.      * @return the Object chosen by the user, UNINITIALIZED_VALUE
  1410.      *         if the user has not yet made a choice, or null if
  1411.      *         the user closed the window without making a choice.
  1412.      *
  1413.      * @see #setValue
  1414.      */
  1415.     public Object getValue() {
  1416.         return value;
  1417.     }
  1418.  
  1419.     /**
  1420.      * Sets the options this pane displays. If an element in
  1421.      * newOptions is a Comonent it is added directly to the pane,
  1422.      * Otherwise a button is created for the element.
  1423.      * @param newOptions an array of Objects that create the buttons
  1424.      *        the user can click on, or arbitrary Components to add
  1425.      *        to the pane
  1426.      *
  1427.      * @see #getOptions
  1428.      * @beaninfo
  1429.      *       bound: true
  1430.      * description: The option pane's options objects.
  1431.      */
  1432.     public void setOptions(Object[] newOptions) {
  1433.         Object[]           oldOptions = options;
  1434.  
  1435.         options = newOptions;
  1436.         firePropertyChange(OPTIONS_PROPERTY, oldOptions, options);
  1437.     }
  1438.  
  1439.     /**
  1440.      * Returns the choices the user can make.
  1441.      * @param the array of Objects that give the user's choices
  1442.      *
  1443.      * @see #setOptions
  1444.      */
  1445.     public Object[] getOptions() {
  1446.         if(options != null) {
  1447.             int             optionCount = options.length;
  1448.             Object[]        retOptions = new Object[optionCount];
  1449.  
  1450.             System.arraycopy(options, 0, retOptions, 0, optionCount);
  1451.             return retOptions;
  1452.         }
  1453.         return options;
  1454.     }
  1455.  
  1456.     /**
  1457.      * Sets the initial value that is to be enabled -- the Component
  1458.      * that has the focus when the pane is initially displayed.
  1459.      *
  1460.      * @param newInitialValue the Object that gets the initial 
  1461.      *                         keyboard focus
  1462.      *
  1463.      * @see #getInitialValue
  1464.      * @beaninfo
  1465.      *   preferred: true
  1466.      *       bound: true
  1467.      * description: The option pane's initial value object.
  1468.      */
  1469.     public void setInitialValue(Object newInitialValue) {
  1470.         Object            oldIV = initialValue;
  1471.  
  1472.         initialValue = newInitialValue;
  1473.         firePropertyChange(INITIAL_VALUE_PROPERTY, oldIV, initialValue);
  1474.     }
  1475.  
  1476.     /**
  1477.      * Returns the initial value.
  1478.      *
  1479.      * @return the Object that gets the initial keyboard focus
  1480.      *
  1481.      * @see #setInitialValue
  1482.      */
  1483.     public Object getInitialValue() {
  1484.         return initialValue;
  1485.     }
  1486.  
  1487.     /**
  1488.      * Sets the option pane's message type.
  1489.      * The message type is used by the look and feel to determine the
  1490.      * icon to display (if not supplied) as well as potentially how to
  1491.      * lay out the parentComponent.
  1492.      * @param newType an int specifying the kind of message to display:
  1493.      *                ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE,
  1494.      *                QUESTION_MESSAGE, or PLAIN_MESSAGE. Otherwise, 
  1495.      *                a RuntimeEception is thrown.
  1496.  
  1497.      * @see #getMessageType
  1498.      * @beaninfo
  1499.      *   preferred: true
  1500.      *       bound: true
  1501.      * description: The option pane's message type.
  1502.      */
  1503.     public void setMessageType(int newType) {
  1504.         if(newType != ERROR_MESSAGE && newType != INFORMATION_MESSAGE &&
  1505.            newType != WARNING_MESSAGE && newType != QUESTION_MESSAGE &&
  1506.            newType != PLAIN_MESSAGE)
  1507.             throw new RuntimeException("JOptionPane: type must be one of JOptionPane.ERROR_MESSAGE, JOptionPane.INFORMATION_MESSAGE, JOptionPane.WARNING_MESSAGE, JOptionPane.QUESTION_MESSAGE or JOptionPane.PLAIN_MESSAGE");
  1508.  
  1509.         int           oldType = messageType;
  1510.  
  1511.         messageType = newType;
  1512.         firePropertyChange(MESSAGE_TYPE_PROPERTY, oldType, messageType);
  1513.     }
  1514.  
  1515.     /**
  1516.      * Returns the message type.
  1517.      *
  1518.      * @return an int specifying the message type
  1519.      *
  1520.      * @see #setMessageType
  1521.      */
  1522.     public int getMessageType() {
  1523.         return messageType;
  1524.     }
  1525.  
  1526.     /**
  1527.      * Sets the options to display. 
  1528.      * The option type is used by the look and feel to
  1529.      * determine what buttons to show (unless options are supplied).
  1530.      * @param newType an int specifying the options the L&F is to display:
  1531.      *                DEFAULT_OPTION, YES_NO_OPTION, YES_NO_CANCEL_OPTION,
  1532.      *                or OK_CANCEL_OPTION. Otherwise, a RuntimeException
  1533.      *                is thrown.
  1534.      *
  1535.      * @see #getOptionType
  1536.      * @see #setOptions
  1537.      * @beaninfo
  1538.      *   preferred: true
  1539.      *       bound: true
  1540.      * description: The option pane's option type.
  1541.       */
  1542.     public void setOptionType(int newType) {
  1543.         if(newType != DEFAULT_OPTION && newType != YES_NO_OPTION &&
  1544.            newType != YES_NO_CANCEL_OPTION && newType != OK_CANCEL_OPTION)
  1545.             throw new RuntimeException("JOptionPane: option type must be one of JOptionPane.DEFAULT_OPTION, JOptionPane.YES_NO_OPTION, JOptionPane.YES_NO_CANCEL_OPTION or JOptionPane.OK_CANCEL_OPTION");
  1546.  
  1547.         int            oldType = optionType;
  1548.  
  1549.         optionType = newType;
  1550.         firePropertyChange(OPTION_TYPE_PROPERTY, oldType, optionType);
  1551.     }
  1552.  
  1553.     /**
  1554.      * Returns the type of options that are displayed.
  1555.      *
  1556.      * @return an int specifying the user-selectable options
  1557.      *
  1558.      * @see #setOptionType
  1559.      */
  1560.     public int getOptionType() {
  1561.         return optionType;
  1562.     }
  1563.  
  1564.     /** 
  1565.      * Sets the selection values for a pane that provides the user
  1566.      * with a list of items to choose from. (The UI provides a widget 
  1567.      * for choosing one of the values.) 
  1568.      * <p>
  1569.      * Sets <code>wantsInput</code> to true. Use
  1570.      * <code>setInitialSelectionValue</code> to specify the initially-chosen
  1571.      * value. After the pane as been enabled, inputValue is 
  1572.      * set to the value the user has selected.
  1573.      * @param newValues an array of Objects the user to be displayed
  1574.      *                  (usually in a list or combo-box) from which
  1575.      *                  the user can make a selection
  1576.      * @see #setWantsInput
  1577.      * @see #setInitialSelectionValue
  1578.      * @see #getSelectionValues
  1579.      * @beaninfo
  1580.      *       bound: true
  1581.      * description: The option pane's selection values.
  1582.      */
  1583.     public void setSelectionValues(Object[] newValues) {
  1584.         Object[]           oldValues = selectionValues;
  1585.  
  1586.         selectionValues = newValues;
  1587.         firePropertyChange(SELECTION_VALUES_PROPERTY, oldValues, newValues);
  1588.         if(selectionValues != null)
  1589.             setWantsInput(true);
  1590.     }
  1591.  
  1592.     /**
  1593.      * Returns the selection values.
  1594.      *
  1595.      * @param return the array of Objects the user can select
  1596.      * @see #setSelectionValues
  1597.      */
  1598.     public Object[] getSelectionValues() {
  1599.         return selectionValues;
  1600.     }
  1601.  
  1602.     /**
  1603.      * Sets the initial selection value. Only used if <code>wantsInput</code>
  1604.      * is true.
  1605.      * @param newValue the initially selected value
  1606.      * @see #setSelectionValues
  1607.      * @see #getInitialSelectionValue
  1608.      * @beaninfo
  1609.      *       bound: true
  1610.      * description: The option pane's initial selection value object.
  1611.      */
  1612.     public void setInitialSelectionValue(Object newValue) {
  1613.         Object          oldValue = initialSelectionValue;
  1614.  
  1615.         initialSelectionValue = newValue;
  1616.         firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, oldValue,
  1617.                            newValue);
  1618.     }
  1619.  
  1620.     /**
  1621.      * Returns the initial-selection value..
  1622.      *
  1623.      * @return the initially selected value
  1624.      * @see #setInitialSelectionValue
  1625.      * @see #setSelectionValues
  1626.      */
  1627.     public Object getInitialSelectionValue() {
  1628.         return initialSelectionValue;
  1629.     }
  1630.  
  1631.     /**
  1632.      * Sets the user's input-value.
  1633.      *
  1634.      * @param newValue the Object used to initialized the value that
  1635.      *        the user specified (usually in a text field)
  1636.      * @see #setSelectionValues
  1637.      * @see #setWantsInput
  1638.      * @see #getInputValue
  1639.      * @beaninfo
  1640.      *   preferred: true
  1641.      *       bound: true
  1642.      * description: The option pane's input value object.
  1643.      */
  1644.     public void setInputValue(Object newValue) {
  1645.         Object              oldValue = inputValue;
  1646.  
  1647.         inputValue = newValue;
  1648.         firePropertyChange(INPUT_VALUE_PROPERTY, oldValue, newValue);
  1649.     }
  1650.  
  1651.     /**
  1652.      * Returns the value the user has input, if <code>wantsInput</code>
  1653.      * is true.
  1654.      *
  1655.      * @return the Object the user specified, if it was one of the
  1656.      *         objects, or a String if it was a value typed into a
  1657.      *         field.
  1658.      * @see #setSelectionValues
  1659.      * @see #setWantsInput
  1660.      * @see #setInputValue
  1661.      */
  1662.     public Object getInputValue() {
  1663.         return inputValue;
  1664.     }
  1665.  
  1666.     /**
  1667.      * Returns the maximum number of characters to place on a line in a
  1668.      * message. Default is to return Integer.MAX_VALUE. The value can be 
  1669.      * changed by overriding this method in a subclasse.
  1670.      *
  1671.      * @return an int giving the maximum number of characters on a line
  1672.      */
  1673.     public int getMaxCharactersPerLineCount() {
  1674.         return Integer.MAX_VALUE;
  1675.     }
  1676.  
  1677.     /**
  1678.      * If <code>newValue</code> is true, a parentComponent is provided to
  1679.      * allow the user to input a value. If <code>getSelectionValues</code>
  1680.      * returns a non-null the input value is one of the objects in that 
  1681.      * array. Otherwise the input value is whatever the user inputs.
  1682.      * <p>
  1683.      * This is a bound property.
  1684.      *
  1685.      * @see #setSelectionValues
  1686.      * @see #setInputValue
  1687.      */
  1688.     public void setWantsInput(boolean newValue) {
  1689.         boolean            oldValue = wantsInput;
  1690.  
  1691.         wantsInput = newValue;
  1692.         firePropertyChange(WANTS_INPUT_PROPERTY, oldValue, newValue);
  1693.     }
  1694.  
  1695.     /**
  1696.      * Returns true if a parentComponent will be provided for the user to
  1697.      * input.
  1698.      *
  1699.      * @return true if a parentComponent will be provided
  1700.      * @see #setWantsInput
  1701.      */
  1702.     public boolean getWantsInput() {
  1703.         return wantsInput;
  1704.     }
  1705.  
  1706.     /**
  1707.      * Requests that the initial value be selected, which will set
  1708.      * focus to the initial value. This method
  1709.      * should be invoked after the window containing the option pane
  1710.      * is made visible.
  1711.      */
  1712.     public void selectInitialValue() {
  1713.         OptionPaneUI         ui = getUI();
  1714.         if (ui != null) {
  1715.             ui.selectInitialValue(this);
  1716.         }
  1717.     }
  1718.  
  1719.     
  1720.     // Serialization support.  
  1721.     private void writeObject(ObjectOutputStream s) throws IOException {
  1722.         Vector      values = new Vector();
  1723.  
  1724.         s.defaultWriteObject();
  1725.         // Save the icon, if its Serializable.
  1726.         if(icon != null && icon instanceof Serializable) {
  1727.             values.addElement("icon");
  1728.             values.addElement(icon);
  1729.         }
  1730.         // Save the message, if its Serializable.
  1731.         if(message != null && message instanceof Serializable) {
  1732.             values.addElement("message");
  1733.             values.addElement(message);
  1734.         }
  1735.         // Save the treeModel, if its Serializable.
  1736.         if(options != null) {
  1737.             Vector           serOptions = new Vector();
  1738.  
  1739.             for(int counter = 0, maxCounter = options.length;
  1740.                 counter < maxCounter; counter++)
  1741.                 if(options[counter] instanceof Serializable)
  1742.                     serOptions.addElement(options[counter]);
  1743.             if(serOptions.size() > 0) {
  1744.                 int             optionCount = serOptions.size();
  1745.                 Object[]        arrayOptions = new Object[optionCount];
  1746.  
  1747.                 serOptions.copyInto(arrayOptions);
  1748.                 values.addElement("options");
  1749.                 values.addElement(arrayOptions);
  1750.             }
  1751.         }
  1752.         // Save the initialValue, if its Serializable.
  1753.         if(initialValue != null && initialValue instanceof Serializable) {
  1754.             values.addElement("initialValue");
  1755.             values.addElement(initialValue);
  1756.         }
  1757.         // Save the value, if its Serializable.
  1758.         if(value != null && value instanceof Serializable) {
  1759.             values.addElement("value");
  1760.             values.addElement(value);
  1761.         }
  1762.         // Save the selectionValues, if its Serializable.
  1763.         if(selectionValues != null) {
  1764.             boolean            serialize = true;
  1765.  
  1766.             for(int counter = 0, maxCounter = selectionValues.length;
  1767.                 counter < maxCounter; counter++) {
  1768.                 if(selectionValues[counter] != null &&
  1769.                    !(selectionValues[counter] instanceof Serializable)) {
  1770.                     serialize = false;
  1771.                     break;
  1772.                 }
  1773.             }
  1774.             if(serialize) {
  1775.                 values.addElement("selectionValues");
  1776.                 values.addElement(selectionValues);
  1777.             }
  1778.         }
  1779.         // Save the inputValue, if its Serializable.
  1780.         if(inputValue != null && inputValue instanceof Serializable) {
  1781.             values.addElement("inputValue");
  1782.             values.addElement(inputValue);
  1783.         }
  1784.         // Save the initialSelectionValue, if its Serializable.
  1785.         if(initialSelectionValue != null &&
  1786.            initialSelectionValue instanceof Serializable) {
  1787.             values.addElement("initialSelectionValue");
  1788.             values.addElement(initialSelectionValue);
  1789.         }
  1790.         s.writeObject(values);
  1791.     }
  1792.  
  1793.     private void readObject(ObjectInputStream s) 
  1794.         throws IOException, ClassNotFoundException {
  1795.         s.defaultReadObject();
  1796.  
  1797.         Vector          values = (Vector)s.readObject();
  1798.         int             indexCounter = 0;
  1799.         int             maxCounter = values.size();
  1800.  
  1801.         if(indexCounter < maxCounter && values.elementAt(indexCounter).
  1802.            equals("icon")) {
  1803.             icon = (Icon)values.elementAt(++indexCounter);
  1804.             indexCounter++;
  1805.         }
  1806.         if(indexCounter < maxCounter && values.elementAt(indexCounter).
  1807.            equals("message")) {
  1808.             message = values.elementAt(++indexCounter);
  1809.             indexCounter++;
  1810.         }
  1811.         if(indexCounter < maxCounter && values.elementAt(indexCounter).
  1812.            equals("options")) {
  1813.             options = (Object[])values.elementAt(++indexCounter);
  1814.             indexCounter++;
  1815.         }
  1816.         if(indexCounter < maxCounter && values.elementAt(indexCounter).
  1817.            equals("initialValue")) {
  1818.             initialValue = values.elementAt(++indexCounter);
  1819.             indexCounter++;
  1820.         }
  1821.         if(indexCounter < maxCounter && values.elementAt(indexCounter).
  1822.            equals("value")) {
  1823.             value = values.elementAt(++indexCounter);
  1824.             indexCounter++;
  1825.         }
  1826.         if(indexCounter < maxCounter && values.elementAt(indexCounter).
  1827.            equals("selectionValues")) {
  1828.             selectionValues = (Object[])values.elementAt(++indexCounter);
  1829.             indexCounter++;
  1830.         }
  1831.         if(indexCounter < maxCounter && values.elementAt(indexCounter).
  1832.            equals("inputValue")) {
  1833.             inputValue = values.elementAt(++indexCounter);
  1834.             indexCounter++;
  1835.         }
  1836.         if(indexCounter < maxCounter && values.elementAt(indexCounter).
  1837.            equals("initialSelectionValue")) {
  1838.             initialSelectionValue = values.elementAt(++indexCounter);
  1839.             indexCounter++;
  1840.         }
  1841.     if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  1842.         ui.installUI(this);
  1843.     }
  1844.     }
  1845.  
  1846.  
  1847.     /**
  1848.      * Returns a string representation of this JOptionPane. This method 
  1849.      * is intended to be used only for debugging purposes, and the 
  1850.      * content and format of the returned string may vary between      
  1851.      * implementations. The returned string may be empty but may not 
  1852.      * be <code>null</code>.
  1853.      * <P>
  1854.      * Overriding paramString() to provide information about the
  1855.      * specific new aspects of the JFC components.
  1856.      * 
  1857.      * @return  a string representation of this JOptionPane.
  1858.      */
  1859.     protected String paramString() {
  1860.         String iconString = (icon != null ?
  1861.                  icon.toString() : "");
  1862.         String initialValueString = (initialValue != null ?
  1863.                      initialValue.toString() : "");
  1864.         String messageString = (message != null ?
  1865.                 message.toString() : "");
  1866.         String messageTypeString;
  1867.         if (messageType == ERROR_MESSAGE) {
  1868.             messageTypeString = "ERROR_MESSAGE";
  1869.         } else if (messageType == INFORMATION_MESSAGE) {
  1870.             messageTypeString = "INFORMATION_MESSAGE";
  1871.         } else if (messageType == WARNING_MESSAGE) {
  1872.             messageTypeString = "WARNING_MESSAGE";
  1873.         } else if (messageType == QUESTION_MESSAGE) {
  1874.             messageTypeString = "QUESTION_MESSAGE";
  1875.         } else if (messageType == PLAIN_MESSAGE)  {
  1876.             messageTypeString = "PLAIN_MESSAGE";
  1877.         } else messageTypeString = "";
  1878.         String optionTypeString;
  1879.         if (optionType == DEFAULT_OPTION) {
  1880.             optionTypeString = "DEFAULT_OPTION";
  1881.         } else if (optionType == YES_NO_OPTION) {
  1882.             optionTypeString = "YES_NO_OPTION";
  1883.         } else if (optionType == YES_NO_CANCEL_OPTION) {
  1884.             optionTypeString = "YES_NO_CANCEL_OPTION";
  1885.         } else if (optionType == OK_CANCEL_OPTION) {
  1886.             optionTypeString = "OK_CANCEL_OPTION";
  1887.         } else optionTypeString = "";
  1888.         String wantsInputString = (wantsInput ?
  1889.                    "true" : "false");
  1890.  
  1891.         return super.paramString() +
  1892.         ",icon=" + iconString +
  1893.         ",initialValue=" + initialValueString +
  1894.         ",message=" + messageString +
  1895.         ",messageType=" + messageTypeString +
  1896.         ",optionType=" + optionTypeString +
  1897.         ",wantsInput=" + wantsInputString;
  1898.     }
  1899.  
  1900. ///////////////////
  1901. // Accessibility support
  1902. ///////////////////
  1903.  
  1904.     /**
  1905.      * Get the AccessibleContext associated with this JComponent
  1906.      *
  1907.      * @return the AccessibleContext of this JComponent
  1908.      * @beaninfo
  1909.      *       expert: true
  1910.      *  description: The AccessibleContext associated with this option pane
  1911.      */
  1912.     public AccessibleContext getAccessibleContext() {
  1913.         if (accessibleContext == null) {
  1914.             accessibleContext = new AccessibleJOptionPane();
  1915.         }
  1916.         return accessibleContext;
  1917.     }
  1918.  
  1919.     /**
  1920.      * Accessiblity support.
  1921.      * <p>
  1922.      * <strong>Warning:</strong>
  1923.      * Serialized objects of this class will not be compatible with
  1924.      * future Swing releases.  The current serialization support is appropriate
  1925.      * for short term storage or RMI between applications running the same
  1926.      * version of Swing.  A future release of Swing will provide support for
  1927.      * long term persistence.
  1928.      */
  1929.     protected class AccessibleJOptionPane extends AccessibleJComponent {
  1930.  
  1931.         /**
  1932.          * Get the role of this object.
  1933.          *
  1934.          * @return an instance of AccessibleRole describing the role of the object
  1935.          * @see AccessibleRole
  1936.          */
  1937.         public AccessibleRole getAccessibleRole() {
  1938.             return AccessibleRole.OPTION_PANE;
  1939.         }
  1940.  
  1941.     } // inner class AccessibleJOptionPane
  1942. }
  1943.  
  1944.